#pragma once
#include <math.h>
#include "stdafx.h"

namespace Math
{
	double Get_Diagonal_Quadrilateral(double Height, double Width)
	{
		return sqrt( Height * Height + Width * Width );
	}

	double Get_Cam_Height(double Alpha, double Radius)
	{
		return cos(Alpha) * Radius;
	}

	double Get_Cam_Height(double Alpha, double Height, double Width)
	{
		return cos(Alpha) * ( Get_Diagonal_Quadrilateral(Height, Width) / 2);
	}

	double Get_Height_From_Width_and_RealWidth_and_RealHeight(double Width, double RealWidth, double RealHeight)
	{
		return 0;
	}

	D3DXVECTOR3 GetPoint_Vector_Contact_to_Splane(const D3DXPLANE &Plane, const D3DXVECTOR3 &Pos, const D3DXVECTOR3 &Vec3)
	{
		D3DXVECTOR3				Result	=	Vec3;
		double					T;

start_function:

		T	=	(-Plane.d - (double) D3DXVec3Dot( &D3DXVECTOR3( Plane.a, Plane.b, Plane.c ), &D3DXVECTOR3( Pos.x, Pos.y, Pos.z ) ) )
				/ (double) D3DXVec3Dot( &D3DXVECTOR3( Plane.a, Plane.b, Plane.c ), &Result );
		
		if(T <= 0)
		{
			Result.y	-=	0.001f;
			D3DXVec3Normalize		(&Result, &Result);

			goto start_function;
		}

		Result	*=	(float)T;
		Result	+= 	D3DXVECTOR3( Pos.x, Pos.y, Pos.z );

		return Result;
	}
	D3DXVECTOR3 GetPoint_Vector_ContactToSplane(const D3DXPLANE &Plane, const D3DXVECTOR3 &Pos, const D3DXVECTOR3 &Vec3)
	{
		D3DXVECTOR3				Result	=	Vec3;
		double					T;

		T	=	(-Plane.d - (double) D3DXVec3Dot( &D3DXVECTOR3( Plane.a, Plane.b, Plane.c ), &D3DXVECTOR3( Pos.x, Pos.y, Pos.z ) ) )
				/ (double) D3DXVec3Dot( &D3DXVECTOR3( Plane.a, Plane.b, Plane.c ), &Result );

		Result	*=	(float)T;
		Result	+= 	D3DXVECTOR3( Pos.x, Pos.y, Pos.z );

		return Result;
	}

	D3DXVECTOR3 GetPoint_Vector_Length(const D3DXVECTOR3 &Pos,const D3DXVECTOR3 &Dir, float length)
	{
		return Pos + Dir * length;
	}

	double D(double a, double b)
	{
		return a * a - 2 * a * b + b * b;
	}
	float  D(float a,  float  b)
	{
		return a * a - 2 * a * b + b * b;
	}
	int    D(int a,    int    b)
	{
		return a * a - 2 * a * b + b * b;
	}

	double GetVecLength(const D3DXVECTOR3 &v1, const D3DXVECTOR3 &v2)
	{
		return sqrt( D(v1.x, v2.x) + D(v1.y, v2.y) + D(v1.z, v2.z) );
	}
	double GetVecLength(const D3DXVECTOR2 &v1, const D3DXVECTOR2 &v2)
	{
		return sqrt( D(v1.x, v2.x) + D(v1.y, v2.y) );
	}
	double GetVecLength(const POINT &p1,       const POINT &p2)
	{
		return sqrt( (float)D((int)p1.x, (int)p2.x) + D((int)p1.y, (int)p2.y) );
	}
	double GetVecLength(const D3DXVECTOR2 &v1, const POINT &p2)
	{
		return sqrt( D(v1.x, (float)p2.x) + D(v1.y, (float)p2.y) );
	}
	double GetVecLength(const POINT &p1,       const D3DXVECTOR2 &v2)
	{
		return sqrt( D((float)p1.x, v2.x) + D((float)p1.y, v2.y) );
	}

	void From_Projection_to_Real(vector<D3DXVECTOR3> &Result, const D3DXVECTOR3 &CamPos)
	{
		D3DXVECTOR3			v1 = Result[2] - CamPos,
							v2 = Result[3] - CamPos;

		D3DXVec3Normalize(&v1, &v1);
		D3DXVec3Normalize(&v2, &v2);

		D3DXPLANE			p1, 
							p2;

		D3DXPlaneFromPointNormal(&p1, &Result[0], &D3DXVECTOR3(-1.0f, 0.0f, 0.0f));
		D3DXPlaneFromPointNormal(&p2, &Result[1], &D3DXVECTOR3( 1.0f, 0.0f, 0.0f));

		Result[2] = GetPoint_Vector_Contact_to_Splane(p1, CamPos, v1);
		Result[3] = GetPoint_Vector_Contact_to_Splane(p2, CamPos, v2);
	}
}